package com.longxiao.validator;

import com.longxiao.validator.anno.ValiCnMobile;
import com.longxiao.validator.anno.ValiNotBlank;
import com.longxiao.validator.anno.ValiNumber;
import com.longxiao.validator.anno.ValiString;
import com.longxiao.validator.parser.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.LinkedHashMap;

/**
 * 验证框架
 * Created by houhongwei on 2017/5/12.
 */
public class LXValidator {

    private static LinkedHashMap<Class, Parser> parsesMap = new LinkedHashMap<Class, Parser>();

    // private static List<Parser> parsers = new ArrayList<Parser>();

    static {
        // parsers.add(new ValiNotBlankParser());
        // parsers.add(new ValiNumberParser());
        // parsers.add(new ValiStringParser());
        // parsers.add(new ValiCnMobileParser());

        parsesMap.put(ValiNotBlank.class, new ValiNotBlankParser());
        parsesMap.put(ValiNumber.class, new ValiNumberParser());
        parsesMap.put(ValiString.class, new ValiStringParser());
        parsesMap.put(ValiCnMobile.class, new ValiCnMobileParser());

    }

    public static String getName(Annotation anno) {
        if (anno instanceof ValiNotBlank) {
            return ((ValiNotBlank) anno).name();
        } else if (anno instanceof ValiNumber) {
            return ((ValiNumber) anno).name();
        } else if (anno instanceof ValiString) {
            return ((ValiString) anno).name();
        } else if (anno instanceof ValiCnMobile) {
            return ((ValiCnMobile) anno).name();
        }
        return "";
    }



    /**
     * 验证对象
     * @param obj
     * @return
     */
    public static ValidResult validation(Object obj) {
        for (Field field : obj.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            Object value = null;
            try {
                value = field.get(obj);
            } catch (Exception e) {
            }
            Annotation[] declareAnnos = field.getDeclaredAnnotations();// 获得字段上所有的注解
            for (Annotation anno : declareAnnos) {// 迭代注解
                Parser parser = parsesMap.get(anno.annotationType());// 查询是否存在解析器
                if (parser != null) {// 存在解析器
                    ValidResult validResult = parser.doParser(anno, value);// 开始验证
                    if(!validResult.isValid()){// 验证未通过
                        return validResult;
                    }
                }
            }
        }
        return ValidResult.createSucc();
    }

    public static ValidResult validation(Annotation[] annos, Object value) {
        if (annos == null || annos.length == 0) {// 没有注解，返回成功
            return ValidResult.createSucc();
        } else {// 有注解，判断是否为验证注解
            for (Annotation anno : annos) {
                Parser parser = getParse(anno.annotationType());
                if (parser != null) {
                    ValidResult validResult = parser.doParser(anno, value);// 开始验证
                    if(!validResult.isValid()){// 验证未通过
                        return validResult;
                    }
                }
            }
        }
        return ValidResult.createSucc();
    }

    public static Parser getParse(Class key) {
        return parsesMap.get(key);
    }

    public static void addParser(Class key, Parser parser) {
        // parsers.add(parser);
        parsesMap.put(key, parser);
    }



}
